const CFG = require('../config');
const FUN = require('../comm/func');
const rCache = require('../model/redis_cache');
const DB = require('../model/model_data');
const dbHelp = require('../comm/db-helper');
const timLib = require('../comm/time-lib');
const dataCalc = require('../comm/data-calc');
const PMR=require('../utils/policyManger');

module.exports = class Person_Act
{
  //将数据库选项缓存到redis
  //policy 来自数据库的记录
  //opts 数据库json字段的解析对象
  //CacheCallback 存储执行函数
  static InitCache(policy,opts,CacheCallback)
  {
    let obj=PMR.baseParam(policy);//即将缓存到redis的参数

    //检查json选项
    if( parseInt(policy.record_limit)==0 ||
        parseInt(opts.fetch_period)==0 )
    {
      console.error('wrong person-act params',policy.id);
      return false;
    }

    //if(policy.id!=269) return false;

    //json options参数存储
    obj.fetch_period = opts.fetch_period;//采样周期
    obj.cache_expire = Number(opts.fetch_period)+60;//数据缓存reids有效期
    obj.record_limit = policy.record_limit;//数据库条数上限

    if(!opts.quiet) opts.quiet=0;
    if(!opts.time) opts.time='';

    obj.quiet_cnt = opts.quiet;//静默确认周期
    obj.alarm_time = opts.time;//报警周期

    //数据库处理
    dbHelp.createTab(obj.table,policy.uid);

    //缓存主站参数
    obj.hwid = policy.master;
    obj.role = 'master';
    obj.brother = policy.brother;
    CacheCallback(policy.id,policy.master,obj);//记录到缓存

    //开启定时器
    PMR.setSecInter(obj.policy_id,obj.fetch_period);
  }//end InitCache

  //处理json数据
  // topic = {project,devType,func,devId}
  // dConf即InitCache中的obj
  // dataBuf即mq消息内容，buf对象
  static async DataIn(topic, dConf, DataBuf)
  {
    if(topic.func != 'var') return;

    let stamp=timLib.NowStamp();
    let preStamp=timLib.Rounding(dConf.fetch_period,stamp);
    let nodeDevStamp=PMR.rdNode(dConf)+':'+preStamp;

    let jsonStr=DataBuf.toString().replace(/\x00/g,'');
    let varsObj=JSON.parse(jsonStr);//收到的变量值

    //pcyLog('var',varsObj.VAR1);

    //读取上一次的值
    rCache.getKey(PMR.rdNode(dConf),'VAR1').then((old)=>{
      if(old==null || old!=varsObj.VAR1)//var1变值了
      {
        //读上一次时间戳
        rCache.getKey(PMR.rdNode(dConf),'stamp').then(lastStamp=>{
          //pcyLog('[%d] state change %d->%d @%d',dConf.policy_id,old,varsObj.VAR1,(stamp-lastStamp)/1000);
          let gapMs=(stamp-lastStamp)/1000;
          if(old==0 && varsObj.VAR1==1 && gapMs>10)//从无人到有人，静默时间大于一定值
          {
            let alarm_time=dConf.alarm_time.split('-');
            if(alarm_time.length==2)
            {
              let start=parseInt(alarm_time[0].replace(/[^0-9]/g,''));
              let end=parseInt(alarm_time[1].replace(/[^0-9]/g,''));
              if(!isNaN(start) && !isNaN(end))
              {
                let now=timLib.CurrHourMinute();
                if(start<end && (start<=now && now<=end))
                {
                  pcyLog('[%d] person active',dConf.policy_id);
                }
                else if(start>end && (start<=now || now<=end))
                {
                  pcyLog('[%d] person active',dConf.policy_id);
                }
              }
            }
          }
          rCache.setKey(PMR.rdNode(dConf),'stamp',stamp,86400);//存时间戳
          rCache.setKey(PMR.rdNode(dConf),'VAR1',varsObj.VAR1,86400);//存新值
          rCache.incKey(nodeDevStamp,'VAR1-cnt',dConf.cache_expire);//计数
        })//end get key stamp
      }
    })//end get key VAR1
  }

  //周期回调
  static SecInter(dConf,nowStamp)
  {
    let preStamp=timLib.Rounding(dConf.fetch_period,nowStamp);
    let nodeDevStamp=PMR.rdNode(dConf,preStamp);

    //处理前一个数据，为提高效率，此处不能用await
    rCache.getKey(nodeDevStamp,'VAR1-cnt').then((val)=>{
      if(val!=0)//null没数据-记零，>0正常记录，0处理完毕
      {
        this.prevDataHandler(PMR.rdNode(dConf),dConf,val?val:0,preStamp);
      }
    })
  }

  //处理前一个时间段的数据
  static async prevDataHandler(nodeDev,dConf,count,preStamp)
  {
    let stamp=timLib.NowStamp();
    let nodeStampNode=nodeDev+':'+preStamp;

    let db_stamp=await rCache.getKey(nodeDev,'db_stamp');
    if(db_stamp!=null && stamp-db_stamp<CFG.DATA_SAVE_GAP)//存储到数据库的频率不能过快
    {pcyLog('[%d] mdata fast(%dmS)',dConf.policy_id,stamp-db_stamp,timLib.NowStr());return;}

    //输出到数据库
    if(dConf.table.includes('dat_json')){
      DB.newRcd(dConf.uid,dConf.table,'hwid,policy_id,addr,json,stamp',[dConf.hwid,dConf.policy_id,1,{'PCNT':count},preStamp]);
      PMR.policyInform('update',dConf);
    }
    // else if(dConf.table.includes('dat_var')){
    //   DB.newRcd(dConf.uid,dConf.table,'hwid,policy_id,vtag,value,stamp',[dConf.hwid,dConf.policy_id,'PCNT',count,preStamp]);
    //   PMR.policyInform('update',dConf);
    // }
    rCache.setKey(nodeDev,'db_stamp',timLib.NowStamp(),60);//记录数据库访问时间戳
    pcyLog('[%d][%d] VarCnt %d',dConf.policy_id,dConf.hwid,count,preStamp,timLib.Stamp2Str(preStamp));

    //处理静默报警
    if(count==0)
    {
      rCache.getKey(PMR.rdNode(dConf),'quiet_cnt').then((quiet_cnt)=>{
        if(quiet_cnt && quiet_cnt==dConf.quiet_cnt)//安静周期超过了指定循环数
        {
          pcyLog('[%d] person quiet alarm',dConf.policy_id,quiet_cnt);

        }
        rCache.incKey(PMR.rdNode(dConf),'quiet_cnt',86400);
      })
    }
    else
    {
      rCache.del(PMR.rdNode(dConf),'quiet_cnt');
    }

    //删除缓存中的使用过的数据
    rCache.del(nodeStampNode,'VAR1-cnt');

    //删除数据库中冗余的前期数据
    dataCalc.dbRecordTidy(dConf.uid,dConf.table,dConf.policy_id,dConf.record_limit);
    if(dConf.out && dConf.calc && dConf.out_tab)
      dataCalc.dbRecordTidy(dConf.uid,dConf.out_tab,dConf.policy_id,dConf.record_limit);
  }//end function



}